/*
 * DNFTree.cpp
 *
 * Copyright 2012 Fabian Wenzelmann
 *
 * This file is part of Recognition-Procedures-for-Boolean-Functions.
 *
 * Recognition-Procedures-for-Boolean-Functions is free software: you
 * can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * Recognition-Procedures-for-Boolean-Functions is distributed in the hope
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Recognition-Procedures-for-Boolean-Functions.
 *
 * If not, see <http://www.gnu.org/licenses/>.
 */

#include "bfr/lpbLP/DNFTree.hpp"

#include <cassert>

#include <utility>
#include <vector>

#include "bfr/ClauseSet.hpp"

namespace bfr {

const size_t DNFTree::npos = -1;

DNFTree::DNFTree()
    //: nodes(), children(), final(), depths(), content() { }
      : content() { }

DNFTree::~DNFTree() {
    for (size_t i = 0; i < content.size(); i++) {
        const content_t *dnf = content[i].dnf;
        if (dnf == 0)
            continue;
        for (content_t::const_iterator it = dnf->begin();
             it != dnf->end();
             it++) {
            delete *it;
        }
        delete dnf;
    }
}

size_t DNFTree::createRoot(const content_t *dnf, bool isFinal) {
    return createNodeEntry(dnf, 0, isFinal);
}

size_t DNFTree::createNodeEntry(const content_t *dnf,
                                size_t depth, bool isFinal) {
    /*nodes.push_back(entry_t(dnf, children.size()));
    final.push_back(isFinal);
    depths.push_back(depth);
    children.push_back(DNFTree::npos);
    children.push_back(DNFTree::npos);
    return nodes.size() - 1;*/
    content.push_back(NodeContent(dnf, DNFTree::npos, DNFTree::npos,
                    isFinal, depth));
    return content.size() - 1;
}

DNFTree::NodeContent& DNFTree::getNode(size_t id) {
	return content[id];
}

size_t DNFTree::createLeftChild(size_t nodeID, const content_t *dnf,
                                bool isFinal) {
    /*size_t firstChildPos = nodes[nodeID].second;
    size_t id = createNodeEntry(dnf, depth, isFinal);
    children[firstChildPos] = id;
    return id;*/
	assert(nodeID != DNFTree::npos);
	assert(nodeID < content.size());
    size_t id = createNodeEntry(dnf, content[nodeID].depth + 1, isFinal);
    content[nodeID].leftChild = id;
    return id;
}

size_t DNFTree::createRightChild(size_t nodeID, const content_t *dnf,
                                 bool isFinal) {
    /*size_t firstChildPos = nodes[nodeID].second;
    size_t id = createNodeEntry(dnf, depth, isFinal);
    children[firstChildPos + 1] = id;
    return id;*/
	assert(nodeID != DNFTree::npos);
	assert(nodeID < content.size());
    size_t id = createNodeEntry(dnf, content[nodeID].depth + 1, isFinal);
    content[nodeID].rightChild = id;
    return id;
}

void DNFTree::deleteEntry(size_t nodeID) {
    /*const content_t *dnf = nodes[nodeID].first;
    for (content_t::const_iterator it = dnf->begin();
         it != dnf->end();
         it++) {
        delete *it;
    }
    delete dnf;*/
    const content_t *dnf = content[nodeID].dnf;
    if (dnf == 0)
        return;
    for (content_t::const_iterator it = dnf->begin();
         it != dnf->end();
         it++) {
        delete *it;
    }
    delete dnf;
    content[nodeID].dnf = 0;
}

} // namespace bfr
